/**
 * \file TableFichiers.c
 * \brief Les descriptions des fonctions de la table des
 * fichiers.
 *
 * Ce fichier contient plusieurs fonctions qui permettent
 * de définir et d'accéder à une structure de tables de 
 * fichiers qui seront disponibles sur le serveur dans le
 * dossier /file.
 * Elle permet d'avoir toutes les informations sur un
 * fichier dans la table.
 *
 */
 
/****************  Includes  ****************/

#include "table_fichiers.h"

/****************  Static function  ****************/


/*********************************
 * CREATION D'UNE TABLE VIDE     *
 *********************************/

TableFichiers init_table(){
  TableFichiers table;
  table.fin_table = 0;
  return table;
}

/***************************************
 * RECHERCHE D'UN FICHIER AVEC SA CLE  *
 ***************************************/

/* La fonction écrit dans un buffer le
   nom du fichier trouvé qui correspond
   à la clé donnée en entrée, dans la
   table passée en paramètre.*/

/* Pas encore implémentée! */


EntreeTable trouver_fichier(TableFichiers table, unsigned char * clef){
  int i = 0;
  //EntreeTable fichier;
  for (i=0;i<table.fin_table;i++){
    if(strncmp(clef,table.contenu[i].clef,TAILLE_MD5*2) == 0){
      return table.contenu[i];
    }   
  }
  perror("ERROR : ...NO FILE MATCHING KEY FOUND..."); // Fichier non trouvé
}

/****************************************
 * RECHERCHE D'UN FICHIER AVEC SON NOM  *
 ****************************************/


EntreeTable trouver_fichier_nom(char * nom_fichier, TableFichiers table){

  //EntreeTable fichier;
  int fin_table = table.fin_table;
  int i;

  for (i=0;i<fin_table;i++){
    if(strcmp(nom_fichier,table.contenu[i].nom_fichier) == 0){
      return table.contenu[i];
    }
  }
  perror("ERROR : ...NO FILE MATCHING NAME FOUND..."); // Fichier non trouvé
}



/*****************************************
 * DONNER UN PORT ALEATOIRE A UN FICHIER *
 *****************************************/

int donner_port_initial (EntreeTable fichier){

  //Choisir un port au hasard entre PORTMIN et PORTMAX
  srand(time(NULL));
  int port=rand()%(PORTMAX-PORTMIN+1)+PORTMIN;
  return port;
}



/********************************************************
 * REMPLISSAGE DE LA TABLE                              *
 ********************************************************/

int remplir_table (char * nom_repertoire, TableFichiers * table){

  /* On écrit dans une structure EntreeTable (un fichier avec ses données) 
     les fichiers contenus dans le répertoire /file ainsi que leur taille, port et clé.
     Puis on ajoute cette EntreeTable dans la table des fichiers. */

  DIR * repertoire;
  struct dirent* entree;
  EntreeTable fichier;
  //int fin_table;
  struct stat statut; // Verification du type d'un fichier

  int port_initial = donner_port_initial(fichier);
  int port_augment = 0;

  unsigned char clef_bits[TAILLE_MD5];
  
  repertoire = opendir(nom_repertoire);
  
  // Ouverture du repertoire ou se trouvent les fichiers
  if (!repertoire) { 
  	perror("ERROR : ...UPLOAD REPERTORY UNKNOWN..."); // Fichier non trouvé
    //perror("Erreur à l'ouverture du répertoire");  
    exit(1);
  }
  // Changement de répertoire
  if(chdir(nom_repertoire)==-1){
    perror("ERROR : ...SWITCHING REPERTORY FAILED...");
  }
  
  // Remplissage de la table
  while ((entree = readdir (repertoire)) != NULL  ){

    stat(entree->d_name,&statut);
    
    if(S_ISREG(statut.st_mode)){   
      
      fichier.nom_fichier = entree->d_name;
      fichier.taille = taille_fichier(fichier.nom_fichier);
      fichier.ip = get_my_ip();
      fichier.port = port_initial + port_augment;
      port_augment++;
 
      // récupération du md5
      cle(fichier.nom_fichier,clef_bits);
      transforme_cle(fichier.clef,clef_bits);
      // fin de la récupération du md5
     
      table->contenu[table->fin_table] = fichier; 
      table->fin_table++;

      
    }
    
    else {
      //perror("S_ISREG erreur - pas un fichier");
    }
  }
  
  if(chdir(REPERTOIRE_SRC)==-1){
    //perror("Erreur lors du retour dans le répertoire source");
  }
  
  closedir(repertoire);
    
  return table->fin_table;
  
}

void afficher_table(TableFichiers table){
	int i;
    fprintf(stderr, "----BEGIN DUMP----\n");
	
	printf("NbEntrée : %d\n", table.fin_table);
	for (i=0; i<table.fin_table; i++)
		printf("Entrée : %s %ld %s %s %d\n", table.contenu[i].nom_fichier, table.contenu[i].taille, table.contenu[i].clef, table.contenu[i].ip, table.contenu[i].port); 
    
    fprintf(stderr, "----END DUMP---- NBRELEMENTS : %d\n", i);
}

